{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import keras\n",
    "from keras import layers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /Users/vaibhavverdhan/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    }
   ],
   "source": [
    "# This is the size of our encoded representations\n",
    "encoding_dim = 32  # 32 floats -> compression of factor 24.5, assuming the input is 784 floats\n",
    "\n",
    "# This is our input image\n",
    "input_img = keras.Input(shape=(784,))\n",
    "# \"encoded\" is the encoded representation of the input\n",
    "encoded = layers.Dense(encoding_dim, activation='relu')(input_img)\n",
    "# \"decoded\" is the lossy reconstruction of the input\n",
    "decoded = layers.Dense(784, activation='sigmoid')(encoded)\n",
    "\n",
    "# This model maps an input to its reconstruction\n",
    "autoencoder = keras.Model(input_img, decoded)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This model maps an input to its encoded representation\n",
    "encoder = keras.Model(input_img, encoded)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is our encoded (32-dimensional) input\n",
    "encoded_input = keras.Input(shape=(encoding_dim,))\n",
    "# Retrieve the last layer of the autoencoder model\n",
    "decoder_layer = autoencoder.layers[-1]\n",
    "# Create the decoder model\n",
    "decoder = keras.Model(encoded_input, decoder_layer(encoded_input))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "autoencoder.compile(optimizer='adam', loss='binary_crossentropy')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "(x_train, _), (x_test, _) = mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(60000, 784)\n",
      "(10000, 784)\n"
     ]
    }
   ],
   "source": [
    "x_train = x_train.astype('float32') / 255.\n",
    "x_test = x_test.astype('float32') / 255.\n",
    "x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))\n",
    "x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))\n",
    "print(x_train.shape)\n",
    "print(x_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /Users/vaibhavverdhan/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n",
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/5\n",
      "60000/60000 [==============================] - 2s 32us/step - loss: 0.2271 - val_loss: 0.1579\n",
      "Epoch 2/5\n",
      "60000/60000 [==============================] - 2s 26us/step - loss: 0.1409 - val_loss: 0.1252\n",
      "Epoch 3/5\n",
      "60000/60000 [==============================] - 1s 24us/step - loss: 0.1184 - val_loss: 0.1103\n",
      "Epoch 4/5\n",
      "60000/60000 [==============================] - 1s 24us/step - loss: 0.1072 - val_loss: 0.1025\n",
      "Epoch 5/5\n",
      "60000/60000 [==============================] - 1s 25us/step - loss: 0.1009 - val_loss: 0.0974\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f852e2bfd30>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "autoencoder.fit(x_train, x_train,\n",
    "                epochs=5,\n",
    "                batch_size=128,\n",
    "                shuffle=True,\n",
    "                validation_data=(x_test, x_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Encode and decode some digits\n",
    "# Note that we take them from the *test* set\n",
    "encoded_imgs = encoder.predict(x_test)\n",
    "decoded_imgs = decoder.predict(encoded_imgs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABG0AAADnCAYAAACkCqtqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAABFLUlEQVR4nO3dd7wU1f3/8UOsKIiAIKJSBLGAiIKACgSUaCzYIspX5Gs0tkSjKSKJMZaoKZgYE7t+LVgSib0BtiBGkfgTEaSIASlSlSKKvdzfH3n48X0+7Ax7l929c3dfz78+4zl3d5jZMzs7ns/5NKipqQkAAAAAAADIlm/V9Q4AAAAAAABgXTy0AQAAAAAAyCAe2gAAAAAAAGQQD20AAAAAAAAyiIc2AAAAAAAAGcRDGwAAAAAAgAzauDadGzRoQH3wOlJTU9OgGK/DOaxTK2pqaloU44U4j3WHsVgRGIsVgLFYERiLFYCxWBEYixWAsVgRco5FZtoA5bOgrncAQAiBsQhkBWMRyAbGIpANOcciD20AAAAAAAAyiIc2AAAAAAAAGcRDGwAAAAAAgAzioQ0AAAAAAEAG8dAGAAAAAAAgg3hoAwAAAAAAkEE8tAEAAAAAAMggHtoAAAAAAABk0MZ1vQOoTuedd57FDRs2jNq6du1q8bHHHpv4GjfccIPFL730UtR21113beguAgAAAABQp5hpAwAAAAAAkEE8tAEAAAAAAMggHtoAAAAAAABkEGvaoGxGjx5tcdpaNeqrr75KbDvjjDMsHjhwYNQ2YcIEixcuXJjvLqKOderUKdp+4403LD733HMtvuaaa8q2T9Vsyy23tPjKK6+0WMdeCCFMnjzZ4sGDB0dtCxYsKNHeAQAA1I2mTZta3KZNm7z+xt8T/fSnP7V4+vTpFr/55ptRv6lTpxayi6ggzLQBAAAAAADIIB7aAAAAAAAAZBDpUSgZTYcKIf+UKE2JefLJJy3eaaedon6DBg2yuEOHDlHb0KFDLf7d736X1/ui7u21117RtqbHLVq0qNy7U/W22247i0877TSLfdpi9+7dLT788MOjtuuuu65Eewe19957W/zggw9Gbe3atSvZ+x500EHR9qxZsyx+++23S/a+WD/9jgwhhEcffdTis88+2+Ibb7wx6vfll1+WdscqUMuWLS3+xz/+YfHEiROjfjfffLPF8+fPL/l+fa1JkybRdr9+/SweN26cxZ9//nnZ9gmoDw477DCLjzjiiKitf//+Fnfs2DGv1/NpT23btrV4s802S/y7jTbaKK/XR+Vipg0AAAAAAEAG8dAGAAAAAAAgg0iPQlH16NHD4qOPPjqx34wZMyz20w1XrFhh8dq1ay3edNNNo36TJk2yeM8994zamjdvnuceI0u6desWbX/44YcWP/TQQ2Xem+rTokWLaHvUqFF1tCeorYMPPtjitCnWxeZTcE455RSLhwwZUrb9wH/pd9/111+f2O/aa6+1+LbbbovaPv744+LvWIXRqjEhxPc0moq0fPnyqF9dpURphb8Q4mu9prfOmTOn9DtWz2y11VbRtqbcd+nSxWJfxZRUs2zTZRXOOussizUVPIQQGjZsaHGDBg02+H19lVQgX8y0AQAAAAAAyCAe2gAAAAAAAGQQD20AAAAAAAAyqE7XtPEloDWPcMmSJVHbJ598YvE999xj8bJly6J+5OPWLS0R7HM/Nedb119YunRpXq/985//PNrefffdE/s+8cQTeb0m6p7mhGsZ2hBCuOuuu8q9O1XnnHPOsfioo46K2nr27Fnr19NSsiGE8K1vffP/BqZOnWrx888/X+vXRmzjjb/5Cj/00EPrZB/8Whk/+9nPLN5yyy2jNl2jCqWh42+HHXZI7Pf3v//dYr2/QrJtttnG4tGjR0dtzZo1s1jXEvrxj39c+h1LcOGFF1rcvn37qO2MM86wmPvmdQ0dOtTiK664Imrbcccdc/6NX/tm5cqVxd8xFI1eH88999ySvtcbb7xhsf4WQvFoyXW9VocQr7GqZdpDCOGrr76y+MYbb7T4xRdfjPpl4TrJTBsAAAAAAIAM4qENAAAAAABABtVpetTIkSOj7Xbt2uX1dzqt84MPPojayjntbNGiRRb7f8srr7xStv3Ikscee8xinaoWQnyuVq1aVevX9uVjN9lkk1q/BrJn1113tdinU/gp6Ci+P//5zxbrNNFCHXPMMYnbCxYssPj444+P+vk0G6zfgAEDLN53330t9t9HpeRLH2va6hZbbBG1kR5VfL68+69+9au8/k5TT2tqaoq6T5Vq7733tthPsVe/+c1vyrA36+rcuXO0rSnlDz30UNTGd+u6NF3m6quvtrh58+ZRv6Txcs0110Tbmu5dyD0v8uNTYTTVSVNcxo0bF/X79NNPLV6zZo3F/ntK70ufeuqpqG369OkW//vf/7Z4ypQpUb+PP/448fWRP11OIYR4jOm9pv9M5KtXr14Wf/HFF1Hb7NmzLX7hhReiNv3MffbZZwW9dz6YaQMAAAAAAJBBPLQBAAAAAADIIB7aAAAAAAAAZFCdrmmjJb5DCKFr164Wz5o1K2rbbbfdLE7LK+7du7fFb7/9tsVJJfpy0Ty2d99912ItZ+0tXLgw2q7WNW2Url9RqOHDh1vcqVOnxH6aS5prG9l1/vnnW+w/M4yj0hgzZozFWpK7UFradO3atVFb27ZtLdaysy+//HLUb6ONNtrg/ah0Pp9byzbPnTvX4t/+9rdl26cjjzyybO+Fde2xxx7Rdvfu3RP76r3N2LFjS7ZPlaJly5bR9ve+973Evj/4wQ8s1vvGUtN1bJ555pnEfn5NG78eJEI477zzLNYS7vny67R997vftdiXDdf1b0q5BkalSltnZs8997RYSz17kyZNslh/V86fPz/q16ZNG4t1LdMQirMOINalzwPOOussi/0Y22qrrXL+/eLFi6Ptf/3rXxbPmzcvatPfILq2Ys+ePaN+ek049NBDo7apU6darGXDi42ZNgAAAAAAABnEQxsAAAAAAIAMqtP0qGeffTZ1W/lSbV/z5Ua7detmsU5z2mefffLer08++cTiN99802KfsqVTpXRqOjbM4YcfbrGWztx0002jfu+8847Fv/zlL6O2jz76qER7hw3Vrl27aLtHjx4W63gLgdKIxfLtb3872t5ll10s1um9+U719dM/dXqyls4MIYQDDjjA4rRyxD/84Q8tvuGGG/Laj2pz4YUXRts6RVyn4vsUtWLT7z7/2WK6eHmlpex4Po0A6f70pz9F2yeeeKLFen8ZQgj33XdfWfbJ69u3r8Xbbrtt1HbHHXdYfPfdd5drl+oNTd0NIYSTTz45Z79p06ZF28uXL7d44MCBia/fpEkTizX1KoQQ7rnnHouXLVu2/p2tcv7+/29/+5vFmg4VQpwenJYyqHxKlPLLX6D4brrppmhb09rSynfrc4PXX3/d4gsuuCDqp7/rvf32289ivQ+97bbbon76fEGvASGEcN1111n8wAMPWFzsVFlm2gAAAAAAAGQQD20AAAAAAAAyqE7To4ph9erV0fb48eNz9ktLvUqjU499KpZOxRo9enRBr491abqMnxKp9JhPmDChpPuE4vHpFKqcVTcqnaah3XvvvVFb2nRTpdW8dMrnpZdeGvVLS0fU1zj99NMtbtGiRdRv5MiRFm+++eZR27XXXmvx559/vr7drijHHnusxb5iwZw5cywuZ6U1TXPz6VDPPfecxe+9916Z9qh69evXL7HNV6VJS0/EumpqaqJt/awvWbIkaitlBaCGDRtG2zr1/0c/+pHFfn9POeWUku1TJdB0hxBCaNy4scVabcbfs+j30//8z/9Y7FMyOnToYHGrVq2itkceecTiQw45xOJVq1bls+tVoVGjRhb7JRB0GYUVK1ZEbX/84x8tZqmE7PD3dVq16dRTT43aGjRoYLH+LvCp81deeaXFhS6n0Lx5c4u1iukll1wS9dNlWnxqZbkw0wYAAAAAACCDeGgDAAAAAACQQTy0AQAAAAAAyKB6v6ZNKbRs2dLi66+/3uJvfSt+xqXlqMlDLdzDDz8cbR900EE5+915553Rti9/i/phjz32SGzTdU2wYTbe+JvLe75r2Pi1oYYMGWKxzxvPl65p87vf/c7iq666Kuq3xRZbWOw/B48++qjFc+fOLWg/6qvBgwdbrMcohPj7qdR0jaShQ4da/OWXX0b9Lr/8courbf2hctESpRp7Psf/tddeK9UuVZ3DDjss2tZy6rqWk1+DIV+6jkr//v2jtt69e+f8m/vvv7+g96pWm222WbStawL9+c9/Tvw7LR98++23W6zX6hBC2GmnnRJfQ9daKeV6SPXZUUcdZfEvfvGLqE3LcGvZ+xBCWLNmTUn3C4Xx17Hhw4dbrGvYhBDC4sWLLda1ZV9++eWC3lvXqtlxxx2jNv1tOWbMGIv9OrbK7+9dd91lcSnX8mOmDQAAAAAAQAbx0AYAAAAAACCDSI/K4ayzzrJYy9L68uKzZ88u2z5Vmu22285iP71bp6xqSoZOuw8hhLVr15Zo71BsOp375JNPjtqmTJli8dNPP122fcJ/aaloXyK20JSoJJrmpCk2IYSwzz77FPW96qsmTZpE20mpECEUnnpRCC3Xrul2s2bNivqNHz++bPtUrfIdK+X8fFSiv/zlL9H2gAEDLG7dunXUpqXXder8EUccUdB762v4Ut7qrbfestiXnEY6LdftafqbT+FP0qNHj7zfe9KkSRZzL5tbWuqn3jcuWrSoHLuDDaQpSiGsm1qtvvjiC4t79epl8bHHHhv123XXXXP+/ccffxxt77bbbjnjEOL73G233TZxn9Ty5cuj7XKlhTPTBgAAAAAAIIN4aAMAAAAAAJBBpEeFEPbff/9o269S/jVdyTyEEKZPn16qXap4DzzwgMXNmzdP7Hf33XdbXG1VYyrJwIEDLW7WrFnUNm7cOIu1KgOKx1e+Uzr1tNR0yr/fp7R9vOSSSyweNmxY0fcrS3xFk+23397iv//97+XeHdOhQ4ec/53vwfJLS8MoRuUi/NfkyZOj7a5du1rcrVu3qO273/2uxVoV5d133436jRo1Kq/31mokU6dOTew3ceJEi7lHqh1/PdVUNk1B9CkYWgHz6KOPtthXm9Gx6NtOO+00i/Vcz5w5M59drwo+FUbpeLv44oujtkceecRiKuZlxz//+c9oW1Op9TdCCCG0adPG4r/+9a8Wp6WKarqVT8VKk5QS9dVXX0XbDz30kMXnnHNO1LZ06dK8329DMNMGAAAAAAAgg3hoAwAAAAAAkEE8tAEAAAAAAMgg1rQJIRx66KHR9iabbGLxs88+a/FLL71Utn2qRJovvPfeeyf2e+655yz2uaqon/bcc0+LfU7q/fffX+7dqQpnnnmmxT43t64MGjTI4r322itq0330+6tr2lS6Dz74INrWnHxdUyOEeH2oVatWFXU/WrZsGW0nrS/wwgsvFPV9kVufPn0sPuGEExL7rVmzxmJK4RbX6tWrLfal7XV7xIgRG/xeO+20k8W6FlgI8TXhvPPO2+D3qlbPPPNMtK1jR9et8evMJK2r4V/vrLPOsvjxxx+P2nbeeWeLdX0M/d6udi1atLDY3xPo2m8XXXRR1HbhhRdafOONN1qsZdZDiNdNmTNnjsUzZsxI3KfOnTtH2/q7kOttOl+GW9eD2nrrraM2XVtW151duXJl1G/hwoUW62dCf3OEEELPnj1rvb8333xztH3BBRdYrOtVlRMzbQAAAAAAADKIhzYAAAAAAAAZVLXpUQ0bNrRYS8eFEMJnn31msabnfP7556XfsQriS3nr1DJNQfN06u/atWuLvl8oj1atWlnct29fi2fPnh310zJ6KB5NRSonndIcQgi77767xXoNSOPL5FbTtddPIdYyvt/73veitieeeMLiq666qtbv1aVLl2hbUzLatWsXtSWlBGQl9a7S6ffpt76V/P/bnn766XLsDkpMUz782NP0K3+tRP58Sulxxx1nsaZtN2nSJPE1rrnmGot9Wtwnn3xi8YMPPhi1afrHwQcfbHGHDh2iftVcxv2Pf/yjxT/72c/y/ju9Pv7oRz/KGReLjj9d2mHIkCFFf69K5tONdHwU4s4774y209KjNCVdP2d33HFH1E9LitcVZtoAAAAAAABkEA9tAAAAAAAAMoiHNgAAAAAAABlUtWvaDB8+3GJfenbcuHEWT5w4sWz7VGl+/vOfR9v77LNPzn4PP/xwtE2Z78rw/e9/32ItHzx27Ng62BuUy69+9atoW8ueppk/f77FJ510UtSmZR2rjV4Pfenfww47zOK///3vtX7tFStWRNu6dsY222yT12v4vG+URlLJdb8WwE033VSGvUGxDR48ONr+3//9X4t1zYUQ1i17i+LQkt063k444YSon445XXtI17DxLrvssmh7t912s/iII47I+XohrPtdWE10XZPRo0dHbX/7298s3njj+KfsjjvuaHHa+l/FoGv46WdGy46HEMLll19e0v1ACOeff77FtVlT6Mwzz7S4kPuocmKmDQAAAAAAQAbx0AYAAAAAACCDqiY9SqeRhxDCr3/9a4vff//9qO03v/lNWfap0uVbou/ss8+OtinzXRnatm2b87+vXr26zHuCUhszZozFu+yyS0GvMXPmTItfeOGFDd6nSvHGG29YrCVpQwihW7duFnfs2LHWr61lbb1Ro0ZF20OHDs3Zz5coR3HssMMO0bZP0fjaokWLou1XXnmlZPuE0jnkkEMS2x5//PFo+9VXXy317lQ9TZXSuFD+OqnpPpoeNWDAgKhfs2bNLPYlyiudllj217VOnTol/t2BBx5o8SabbGLxJZdcEvVLWrKhUJq+3L1796K+NnI79dRTLdaUNJ8yp2bMmBFtP/jgg8XfsRJhpg0AAAAAAEAG8dAGAAAAAAAggyo6Pap58+YW//Wvf43aNtpoI4t1an8IIUyaNKm0O4aITv8MIYTPP/+81q+xZs2axNfQ6ZFNmjRJfI2tt9462s43vUuncI4YMSJq++ijj/J6jUp0+OGH5/zvjz32WJn3pDrpVN20Cgpp0/Jvvvlmi1u3bp3YT1//q6++yncXI4MGDSro76rZa6+9ljMuhrfeeiuvfl26dIm2p0+fXtT9qFb77bdftJ00hn31RdRP/jr84YcfWvynP/2p3LuDEvvHP/5hsaZHHX/88VE/XT6ApRvy8+yzz+b875pOHEKcHvXFF19YfPvtt0f9brnlFot/8pOfRG1JaasojZ49e0bbem1s1KhR4t/pshtaLSqEED799NMi7V3pMdMGAAAAAAAgg3hoAwAAAAAAkEE8tAEAAAAAAMigilvTRteqGTdunMXt27eP+s2dO9diLf+N8ps2bdoGv8Z9990XbS9dutTibbfd1mKfL1xsy5Yti7avuOKKkr5flvTp0yfabtWqVR3tCUII4YYbbrB45MiRif20nGzaejT5rlWTb78bb7wxr36oG7omUq7tr7GGTWnomnzeihUrLP7LX/5Sjt1BCejaCnqfEkII77zzjsWU+K48+j2p389HHnlk1O/iiy+2+N57743a3nzzzRLtXWV66qmnom29P9cS0aeddlrUr2PHjhb3798/r/datGhRAXuI9fFrHzZu3DhnP10TLIR43agXX3yx+DtWJsy0AQAAAAAAyCAe2gAAAAAAAGRQxaVHdejQweLu3bsn9tNyzpoqheLxpdT9tM9iGjx4cEF/p2X+0tI6Hn30UYtfeeWVxH7/+te/CtqPSnD00UdH25qqOGXKFIuff/75su1TNXvwwQctHj58eNTWokWLkr3vu+++G23PmjXL4tNPP91iTWFE9tTU1KRuo7QOPvjgxLaFCxdavGbNmnLsDkpA06P8+HriiScS/05TApo2bWqxfi5Qf7z22msWX3TRRVHblVdeafFvf/vbqG3YsGEWf/zxx6XZuQqi9yIhxGXXjzvuuMS/GzBgQGLbl19+abGO2V/84heF7CJy0Ovd+eefn9ff3HPPPdH2c889V8xdqjPMtAEAAAAAAMggHtoAAAAAAABkEA9tAAAAAAAAMqjer2nTtm3baNuXdPuaX9NBy9yiNI455phoW3MRN9lkk7xeo3PnzhbXplz3bbfdZvH8+fMT+z3wwAMWv/HGG3m/Pv5riy22sPjQQw9N7Hf//fdbrDnAKJ0FCxZYPGTIkKjtqKOOsvjcc88t6vv6MvfXXXddUV8f5bH55psntrF+Qmno96Kuz+d98sknFn/++ecl3SfUDf2eHDp0aNT205/+1OIZM2ZYfNJJJ5V+x1BSd955Z7R9xhlnWOzvqX/zm99YPG3atNLuWAXw31s/+clPLG7UqJHFPXr0iPq1bNnSYv974q677rL4kksu2fCdRAghPh8zZ860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\n",
      "text/plain": [
       "<Figure size 1440x288 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Use Matplotlib (don't ask)\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "n = 10  # How many digits we will display\n",
    "plt.figure(figsize=(20, 4))\n",
    "for i in range(n):\n",
    "    # Display original\n",
    "    ax = plt.subplot(2, n, i + 1)\n",
    "    plt.imshow(x_test[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "\n",
    "    # Display reconstruction\n",
    "    ax = plt.subplot(2, n, i + 1 + n)\n",
    "    plt.imshow(decoded_imgs[i].reshape(28, 28))\n",
    "    plt.gray()\n",
    "    ax.get_xaxis().set_visible(False)\n",
    "    ax.get_yaxis().set_visible(False)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_img = keras.Input(shape=(784,))\n",
    "encoded = layers.Dense(128, activation='relu')(input_img)\n",
    "encoded = layers.Dense(64, activation='relu')(encoded)\n",
    "encoded = layers.Dense(32, activation='relu')(encoded)\n",
    "\n",
    "decoded = layers.Dense(64, activation='relu')(encoded)\n",
    "decoded = layers.Dense(128, activation='relu')(decoded)\n",
    "decoded = layers.Dense(784, activation='sigmoid')(decoded)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/100\n",
      "60000/60000 [==============================] - 2s 40us/step - loss: 0.2478 - val_loss: 0.1694\n",
      "Epoch 2/100\n",
      "60000/60000 [==============================] - 2s 30us/step - loss: 0.1521 - val_loss: 0.1372\n",
      "Epoch 3/100\n",
      "60000/60000 [==============================] - 2s 31us/step - loss: 0.1321 - val_loss: 0.1251\n",
      "Epoch 4/100\n",
      "60000/60000 [==============================] - 2s 31us/step - loss: 0.1229 - val_loss: 0.1190\n",
      "Epoch 5/100\n",
      "60000/60000 [==============================] - 2s 33us/step - loss: 0.1174 - val_loss: 0.1136\n",
      "Epoch 6/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.1124 - val_loss: 0.1088\n",
      "Epoch 7/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.1087 - val_loss: 0.1059\n",
      "Epoch 8/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.1060 - val_loss: 0.1037\n",
      "Epoch 9/100\n",
      "60000/60000 [==============================] - 2s 33us/step - loss: 0.1038 - val_loss: 0.1014\n",
      "Epoch 10/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.1016 - val_loss: 0.0998\n",
      "Epoch 11/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0999 - val_loss: 0.0982\n",
      "Epoch 12/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0986 - val_loss: 0.0966\n",
      "Epoch 13/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0973 - val_loss: 0.0956\n",
      "Epoch 14/100\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0961 - val_loss: 0.0945\n",
      "Epoch 15/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.0950 - val_loss: 0.0936\n",
      "Epoch 16/100\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0940 - val_loss: 0.0931\n",
      "Epoch 17/100\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0933 - val_loss: 0.0922\n",
      "Epoch 18/100\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0928 - val_loss: 0.0916\n",
      "Epoch 19/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0922 - val_loss: 0.0912\n",
      "Epoch 20/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0917 - val_loss: 0.0906\n",
      "Epoch 21/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0912 - val_loss: 0.0902\n",
      "Epoch 22/100\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0909 - val_loss: 0.0901\n",
      "Epoch 23/100\n",
      "60000/60000 [==============================] - 2s 33us/step - loss: 0.0905 - val_loss: 0.0895\n",
      "Epoch 24/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0901 - val_loss: 0.0896\n",
      "Epoch 25/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0898 - val_loss: 0.0890\n",
      "Epoch 26/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0894 - val_loss: 0.0885\n",
      "Epoch 27/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0891 - val_loss: 0.0884\n",
      "Epoch 28/100\n",
      "60000/60000 [==============================] - 2s 32us/step - loss: 0.0888 - val_loss: 0.0882\n",
      "Epoch 29/100\n",
      "60000/60000 [==============================] - 2s 33us/step - loss: 0.0885 - val_loss: 0.0879\n",
      "Epoch 30/100\n",
      "60000/60000 [==============================] - 2s 32us/step - loss: 0.0882 - val_loss: 0.0875\n",
      "Epoch 31/100\n",
      "60000/60000 [==============================] - 2s 32us/step - loss: 0.0879 - val_loss: 0.0871\n",
      "Epoch 32/100\n",
      "60000/60000 [==============================] - 2s 32us/step - loss: 0.0876 - val_loss: 0.0870\n",
      "Epoch 33/100\n",
      "60000/60000 [==============================] - 2s 33us/step - loss: 0.0873 - val_loss: 0.0868\n",
      "Epoch 34/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0870 - val_loss: 0.0864\n",
      "Epoch 35/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0868 - val_loss: 0.0859\n",
      "Epoch 36/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0865 - val_loss: 0.0858\n",
      "Epoch 37/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.0863 - val_loss: 0.0858\n",
      "Epoch 38/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.0861 - val_loss: 0.0855\n",
      "Epoch 39/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0859 - val_loss: 0.0858\n",
      "Epoch 40/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0858 - val_loss: 0.0854\n",
      "Epoch 41/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0857 - val_loss: 0.0853\n",
      "Epoch 42/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0855 - val_loss: 0.0855\n",
      "Epoch 43/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0854 - val_loss: 0.0850\n",
      "Epoch 44/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0852 - val_loss: 0.0852\n",
      "Epoch 45/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0850 - val_loss: 0.0845\n",
      "Epoch 46/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0849 - val_loss: 0.0844\n",
      "Epoch 47/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0848 - val_loss: 0.0842\n",
      "Epoch 48/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0847 - val_loss: 0.0843\n",
      "Epoch 49/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0845 - val_loss: 0.0841\n",
      "Epoch 50/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0843 - val_loss: 0.0840\n",
      "Epoch 51/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0842 - val_loss: 0.0837\n",
      "Epoch 52/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0840 - val_loss: 0.0836\n",
      "Epoch 53/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0838 - val_loss: 0.0834\n",
      "Epoch 54/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0837 - val_loss: 0.0832\n",
      "Epoch 55/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0836 - val_loss: 0.0831\n",
      "Epoch 56/100\n",
      "60000/60000 [==============================] - 7s 111us/step - loss: 0.0834 - val_loss: 0.0834\n",
      "Epoch 57/100\n",
      "60000/60000 [==============================] - 3s 43us/step - loss: 0.0834 - val_loss: 0.0831\n",
      "Epoch 58/100\n",
      "60000/60000 [==============================] - 3s 45us/step - loss: 0.0832 - val_loss: 0.0828\n",
      "Epoch 59/100\n",
      "60000/60000 [==============================] - 2s 40us/step - loss: 0.0831 - val_loss: 0.0826\n",
      "Epoch 60/100\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0830 - val_loss: 0.0825\n",
      "Epoch 61/100\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0828 - val_loss: 0.0824\n",
      "Epoch 62/100\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0828 - val_loss: 0.0827\n",
      "Epoch 63/100\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0827 - val_loss: 0.0824\n",
      "Epoch 64/100\n",
      "60000/60000 [==============================] - 2s 41us/step - loss: 0.0826 - val_loss: 0.0822\n",
      "Epoch 65/100\n",
      "60000/60000 [==============================] - 3s 42us/step - loss: 0.0825 - val_loss: 0.0822\n",
      "Epoch 66/100\n",
      "60000/60000 [==============================] - 3s 43us/step - loss: 0.0824 - val_loss: 0.0822\n",
      "Epoch 67/100\n",
      "60000/60000 [==============================] - 2s 41us/step - loss: 0.0823 - val_loss: 0.0820\n",
      "Epoch 68/100\n",
      "60000/60000 [==============================] - 3s 42us/step - loss: 0.0823 - val_loss: 0.0819\n",
      "Epoch 69/100\n",
      "60000/60000 [==============================] - 2s 41us/step - loss: 0.0822 - val_loss: 0.0821\n",
      "Epoch 70/100\n",
      "60000/60000 [==============================] - 2s 41us/step - loss: 0.0822 - val_loss: 0.0820\n",
      "Epoch 71/100\n",
      "60000/60000 [==============================] - 2s 41us/step - loss: 0.0821 - val_loss: 0.0817\n",
      "Epoch 72/100\n",
      "60000/60000 [==============================] - 2s 40us/step - loss: 0.0820 - val_loss: 0.0814\n",
      "Epoch 73/100\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0820 - val_loss: 0.0818\n",
      "Epoch 74/100\n",
      "60000/60000 [==============================] - 2s 41us/step - loss: 0.0819 - val_loss: 0.0817\n",
      "Epoch 75/100\n",
      "60000/60000 [==============================] - 2s 40us/step - loss: 0.0818 - val_loss: 0.0817\n",
      "Epoch 76/100\n",
      "60000/60000 [==============================] - 2s 39us/step - loss: 0.0818 - val_loss: 0.0818\n",
      "Epoch 77/100\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0818 - val_loss: 0.0816\n",
      "Epoch 78/100\n",
      "60000/60000 [==============================] - 2s 38us/step - loss: 0.0817 - val_loss: 0.0815\n",
      "Epoch 79/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.0816 - val_loss: 0.0816\n",
      "Epoch 80/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.0816 - val_loss: 0.0815\n",
      "Epoch 81/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.0815 - val_loss: 0.0815\n",
      "Epoch 82/100\n",
      "60000/60000 [==============================] - 2s 37us/step - loss: 0.0815 - val_loss: 0.0811\n",
      "Epoch 83/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0815 - val_loss: 0.0813\n",
      "Epoch 84/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0815 - val_loss: 0.0814\n",
      "Epoch 85/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0814 - val_loss: 0.0812\n",
      "Epoch 86/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0814 - val_loss: 0.0813\n",
      "Epoch 87/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0813 - val_loss: 0.0811\n",
      "Epoch 88/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0813 - val_loss: 0.0815\n",
      "Epoch 89/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0813 - val_loss: 0.0809\n",
      "Epoch 90/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0812 - val_loss: 0.0812\n",
      "Epoch 91/100\n",
      "60000/60000 [==============================] - 2s 33us/step - loss: 0.0812 - val_loss: 0.0811\n",
      "Epoch 92/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0812 - val_loss: 0.0813\n",
      "Epoch 93/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0811 - val_loss: 0.0812\n",
      "Epoch 94/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0811 - val_loss: 0.0809\n",
      "Epoch 95/100\n",
      "60000/60000 [==============================] - 2s 34us/step - loss: 0.0810 - val_loss: 0.0811\n",
      "Epoch 96/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0810 - val_loss: 0.0808\n",
      "Epoch 97/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0810 - val_loss: 0.0810\n",
      "Epoch 98/100\n",
      "60000/60000 [==============================] - 2s 36us/step - loss: 0.0810 - val_loss: 0.0809\n",
      "Epoch 99/100\n",
      "60000/60000 [==============================] - 2s 35us/step - loss: 0.0810 - val_loss: 0.0808\n",
      "Epoch 100/100\n",
      "60000/60000 [==============================] - 2s 33us/step - loss: 0.0809 - val_loss: 0.0808\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f851dae6400>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "autoencoder = keras.Model(input_img, decoded)\n",
    "autoencoder.compile(optimizer='adam', loss='binary_crossentropy')\n",
    "\n",
    "autoencoder.fit(x_train, x_train,\n",
    "                epochs=100,\n",
    "                batch_size=256,\n",
    "                shuffle=True,\n",
    "                validation_data=(x_test, x_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
